program PingPong; {$APPTYPE CONSOLE}

{$IFDEF FPC}
  {$MODE Delphi}{$H+}
{$ENDIF}

uses
  SysUtils,
  Windows,
  PingPongAction in 'PingPongAction.pas',
  Actors in 'Actors.pas';

{.$DEFINE DUAL_ACTORS}

var
  i, Rounds: Integer;
  Pool: TPooledActors;

  {$IFDEF DUAL_ACTORS}
    PingActor: TPing;
    PongActor: TPong;
  {$ELSE}
    PingPongActor: TPingPong;
  {$ENDIF}
begin
  try
    { 5 Jogos simultaneos, de até 10 rounds, modo verbose }
    Randomize;
    Writeln('*** Teste Verbose');

    Pool := TPooledActors.Create(2);

    {$IFDEF DUAL_ACTORS}
      PingActor := TPing.Create('Ping');
      PongActor := TPong.Create('Pong');

      PingActor.Pong := PongActor;
      PongActor.Ping := PingActor;

      Pool.AddActor(PingActor);
      Pool.AddActor(PongActor);
    {$ELSE}
      PingPongActor := TPingPong.Create('PingPong');

      Pool.AddActor(PingPongActor);
    {$ENDIF}
    ReadLn;                    

    { 5 Jogos simultaneos, de até 10 rounds, modo verbose }
    Randomize;
    WriteLn('*** Teste Verbose');
    for i := 1 to 5 do begin
      Rounds := Random(10) + 1;

      // Current, Total, ShowText, StartTime,
      {$IFDEF DUAL_ACTORS}
         PingActor.Send(PingActor.Ping, [Rounds, Rounds, True, GetTickCount]);
      {$ELSE}
         PingPongActor.Send(PingPongActor.Ping, [Rounds, Rounds, True, GetTickCount]);
      {$ENDIF}     
    end;
    ReadLn;
    
    WriteLn('*** Pool Max Use: ', Pool.ActingMaxCounter);    
    WriteLn('*** Pool Threads: ', Pool.ThreadsActive);
    WriteLn;

    //Pool.ThreadsCount := 2;

    WriteLn('*** Teste Stress');
    { 10 Jogos simultaneos de até 100.000 rounds, modo benchmark}
    for i := 1 to 10 do begin
      Rounds := Random(100000);
      {$IFDEF DUAL_ACTORS}
         PingActor.Send(PingActor.Ping, [Rounds, Rounds, false, GetTickCount]);
      {$ELSE}
         PingPongActor.Send(PingPongActor.Ping, [Rounds, Rounds, false, GetTickCount]);
      {$ENDIF}
    end;
    ReadLn;

    WriteLn('*** Pool Max Use: ', Pool.ActingMaxCounter);
    WriteLn('*** Pool Threads: ', Pool.ThreadsActive);
    WriteLn;          

    //Pool.ThreadsCount := 1;

    Rounds := 1000000;
    WriteLn('*** Teste ', Rounds);
    {$IFDEF DUAL_ACTORS}
       PingActor.Send(PingActor.Ping, [Rounds, Rounds, false, GetTickCount]);
    {$ELSE}
       PingPongActor.Send(PingPongActor.Ping, [Rounds, Rounds, false, GetTickCount]);
    {$ENDIF}
    ReadLn;

    WriteLn('*** Pool Max Use: ', Pool.ActingMaxCounter);
    WriteLn('*** Pool Threads: ', Pool.ThreadsActive);
    WriteLn;        

    ReadLn;

    {$IFDEF DUAL_ACTORS}
       PingActor.Free;
       PongActor.Free;       
    {$ELSE}
       PingPongActor.Free;
    {$ENDIF}

    Pool.Free;
  except
    on E:Exception do
      Writeln(E.Classname, ': ', E.Message);
  end;
end.

